package ca.cbc.msb.mediacms;

import java.util.ArrayList;
import java.util.List;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import ca.cbc.msb.entity.MSBNotification;
import ca.cbc.msb.exception.ThePlatformAuthenticationException;
import ca.cbc.msb.exception.ThePlatformNonBlockingException;
import ca.cbc.msb.exception.ThePlatformSequenceIdNotFoundException;

public class NotificationDigest {
	private static Logger logger = LoggerFactory.getLogger(NotificationDigest.class);

    public class OutputPair {
        long id;
        List<MSBNotification> notifications;

        public OutputPair(List<MSBNotification> notifications, long id) {
            this.id = id;
            this.notifications = notifications;
        }
    }
	/**
	 * This methods takes a JSON notification String from thePlatform and parse into a list of Notification
	 *
     * @param notificationText  The Json Text
     * @return A list of Notification objects.
	 * @throws ThePlatformAuthenticationException The message indicates an authentication Error
	 * @throws ThePlatformNonBlockingException This exception is expected!
	 * @throws ThePlatformSequenceIdNotFoundException Wrong Seq id is provided
	 */
	public OutputPair digest(String notificationText) throws ThePlatformAuthenticationException, ThePlatformNonBlockingException, ThePlatformSequenceIdNotFoundException
	{
		if(notificationText == null || notificationText.equals(""))
		{
			logger.warn("Digesting empty notification JSON text!");
			return null;
		}
		
		List<MSBNotification> nList = new ArrayList<MSBNotification>();
		
		JSONArray jsonArray = JSONArray.fromObject(notificationText);
		try{
			for(int i=0; i<jsonArray.size(); i++)
			{			
				MSBNotification n = new MSBNotification();
				JSONObject jsonObject = jsonArray.getJSONObject(i);
				String methodStr = jsonObject.getString("method").toLowerCase().trim();
				String typeStr = jsonObject.getString("type").toLowerCase().trim();
				n.setId(jsonObject.getLong("id"));
				n.setMethod(methodStr);
				n.setType(methodStr, typeStr);
				
				if(typeStr.equals("release"))
				{		
					JSONObject entryJObject = jsonObject.getJSONObject("entry");
					n.setReleaseId(this.UrlToId(entryJObject.getString("id")));
					n.setMediaId(this.UrlToId(entryJObject.getString("plrelease$mediaId")));
				}
	
				if(typeStr.equals("media"))
				{		
					JSONObject entryJObject = jsonObject.getJSONObject("entry");
					n.setMediaId(this.UrlToId(entryJObject.getString("id")));
				}
				
				nList.add(n);
			}
		} catch (JSONException e) {
			for(int i=0; i<jsonArray.size(); i++)
			{
				JSONObject jsonObject = jsonArray.getJSONObject(i);
				if(jsonObject.has("type") && jsonObject.getString("type").equalsIgnoreCase("exception"))
				{
					JSONObject entryObject = jsonObject.getJSONObject("entry");
					if(entryObject.getString("title").equalsIgnoreCase("ObjectNotFoundException"))
						throw new ThePlatformSequenceIdNotFoundException("The Platform oject not found exception", e);
					else
						throw new ThePlatformAuthenticationException("The platform authentication exception", e);
				} else if(jsonObject.has("id") && jsonObject.entrySet().size() ==1){
                     return new OutputPair(null, jsonObject.getLong("id"));
                }
			}

		}
		
		return new OutputPair(nList, 0);
	}
	
	/**
	 * This methods takes a URL string contains id and strip id from URL
	 * @param urlStr string
	 * @return striped id
	 */
	private long UrlToId(String urlStr)
	{
		urlStr = urlStr.substring(urlStr.lastIndexOf("/")+1);
		return Long.parseLong(urlStr);
	}
}
